#include "InspireRobotsWidget.h"
#include "ui_InspireRobotsWidget.h"

InspireRobotsWidget::InspireRobotsWidget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::InspireRobotsWidget)
{
    ui->setupUi(this);

    m_is_init = false;

    // 通过子线程，轮询设备状态
    // 创建子线程用于轮询设备状态
    m_polling_thread = new QThread;
    m_poller = new StatusPoller(this);
    m_poller->moveToThread(m_polling_thread);

    // 轮询线程启动后执行轮询逻辑
    connect(m_polling_thread, &QThread::started, m_poller, &StatusPoller::startPolling);

    // 轮询结果信号连接到界面更新槽函数
    connect(m_poller, &StatusPoller::statusUpdated, this, [=](QJsonObject status){
        // 更新 UI
        ui->lineEdit_showLittle->setText(QString::number(status["angle_set0"].toInt()));
        ui->lineEdit_showRing->setText(QString::number(status["angle_set1"].toInt()));
        ui->lineEdit_showMiddle->setText(QString::number(status["angle_set2"].toInt()));
        ui->lineEdit_showIndex->setText(QString::number(status["angle_set3"].toInt()));
        ui->lineEdit_showThumbBend->setText(QString::number(status["angle_set4"].toInt()));
        ui->lineEdit_showThumbRotation->setText(QString::number(status["angle_set5"].toInt()));
    }, Qt::ConnectionType::QueuedConnection);

    m_polling_thread->start(); // 启动状态轮询线程

    // 设置输入输入框限制
    ui->lineEdit_inputToolID->setValidator(new QIntValidator(0, 255, this));

    ui->lineEdit_inputLittleAngle->setValidator(new QIntValidator(0, 1000, this));
    ui->lineEdit_inputRingAngle->setValidator(new QIntValidator(0, 1000, this));
    ui->lineEdit_inputMiddleAngle->setValidator(new QIntValidator(0, 1000, this));
    ui->lineEdit_inputIndexAngle->setValidator(new QIntValidator(0, 1000, this));
    ui->lineEdit_inputThumbBendAngle->setValidator(new QIntValidator(0, 1000, this));
    ui->lineEdit_inputThumbRotationAngle->setValidator(new QIntValidator(0, 1000, this));

    ui->lineEdit_inputLittleForce->setValidator(new QIntValidator(0, 1000, this));
    ui->lineEdit_inputRingForce->setValidator(new QIntValidator(0, 1000, this));
    ui->lineEdit_inputMiddleForce->setValidator(new QIntValidator(0, 1000, this));
    ui->lineEdit_inputIndexForce->setValidator(new QIntValidator(0, 1000, this));
    ui->lineEdit_inputThumbBendForce->setValidator(new QIntValidator(0, 1000, this));
    ui->lineEdit_inputThumbRotationAngle->setValidator(new QIntValidator(0, 1000, this));

    ui->lineEdit_inputLittleSpeed->setValidator(new QIntValidator(0, 1000, this));
    ui->lineEdit_inputRingSpeed->setValidator(new QIntValidator(0, 1000, this));
    ui->lineEdit_inputMiddleSpeed->setValidator(new QIntValidator(0, 1000, this));
    ui->lineEdit_inputIndexSpeed->setValidator(new QIntValidator(0, 1000, this));
    ui->lineEdit_inputThumbBendSpeed->setValidator(new QIntValidator(0, 1000, this));
    ui->lineEdit_inputThumbRotationSpeed->setValidator(new QIntValidator(0, 1000, this));

}

InspireRobotsWidget::~InspireRobotsWidget()
{
    delete ui;
    m_polling_thread->quit();
    m_polling_thread->wait();
    delete m_polling_thread;
}

void InspireRobotsWidget::sendRequest(const QJsonObject &requestJson, std::function<void (QJsonArray)> callback)
{
    auto* worker = new JsonWorker(requestJson);

    connect(worker, &JsonWorker::finished, this, [=](QJsonArray result){
        callback(result);
    }, Qt::ConnectionType::QueuedConnection);

    QThreadPool::globalInstance()->start(worker);
}

/**
* @brief 初始化按钮点击槽函数
* 向设备发送设置ID命令作为初始化校验，成功后使能控制按钮和输入框
*/
void InspireRobotsWidget::on_pushButton_init_clicked()
{
    m_is_init = false;
    m_poller->setInit(m_is_init);

    int id = ui->lineEdit_inputToolID->text().toInt();

    QJsonObject init_obj;
    init_obj["slave_id"] = id;
    init_obj["new_slave_id"] = id;

    QJsonObject init_root;
    init_root["set_id"] = init_obj;

    QJsonObject root;
    root["InspireRobotsPlugin"] = init_root;

    sendRequest(root, [=](QJsonArray result){
        if (!result.isEmpty()
                && result[0].toObject()["InspireRobotsPlugin"].toObject()["set_id"].toObject()["return"].toBool())
        {
            m_device_id = id;
            m_is_init = true;

            m_poller->setDeviceId(m_device_id);
            m_poller->setInit(m_is_init);

            ui->lineEdit_ShowToolID->setText(QString::number(m_device_id));
            ui->lineEdit_showState->setText(tr("Initialized"));

            ui->pushButton_run->setEnabled(true);
            ui->pushButton_setForce->setEnabled(true);
            ui->pushButton_setSpeed->setEnabled(true);

            ui->lineEdit_inputLittleAngle->setEnabled(true);
            ui->lineEdit_inputRingAngle->setEnabled(true);
            ui->lineEdit_inputMiddleAngle->setEnabled(true);
            ui->lineEdit_inputIndexAngle->setEnabled(true);
            ui->lineEdit_inputThumbBendAngle->setEnabled(true);
            ui->lineEdit_inputThumbRotationAngle->setEnabled(true);

            ui->lineEdit_inputLittleForce->setEnabled(true);
            ui->lineEdit_inputRingForce->setEnabled(true);
            ui->lineEdit_inputMiddleForce->setEnabled(true);
            ui->lineEdit_inputIndexForce->setEnabled(true);
            ui->lineEdit_inputThumbBendForce->setEnabled(true);
            ui->lineEdit_inputThumbRotationForce->setEnabled(true);

            ui->lineEdit_inputLittleSpeed->setEnabled(true);
            ui->lineEdit_inputRingSpeed->setEnabled(true);
            ui->lineEdit_inputMiddleSpeed->setEnabled(true);
            ui->lineEdit_inputIndexSpeed->setEnabled(true);
            ui->lineEdit_inputThumbBendSpeed->setEnabled(true);
            ui->lineEdit_inputThumbRotationSpeed->setEnabled(true);

        }
        else
        {
            m_is_init = false;
            m_poller->setInit(m_is_init);

            ui->lineEdit_ShowToolID->clear();
            ui->lineEdit_showState->setText(tr("Initialization failed"));
            ui->pushButton_run->setEnabled(false);

            ui->lineEdit_inputLittleAngle->setEnabled(false);
            ui->lineEdit_inputRingAngle->setEnabled(false);
            ui->lineEdit_inputMiddleAngle->setEnabled(false);
            ui->lineEdit_inputIndexAngle->setEnabled(false);
            ui->lineEdit_inputThumbBendAngle->setEnabled(false);
            ui->lineEdit_inputThumbRotationAngle->setEnabled(false);

            ui->lineEdit_inputLittleForce->setEnabled(false);
            ui->lineEdit_inputRingForce->setEnabled(false);
            ui->lineEdit_inputMiddleForce->setEnabled(false);
            ui->lineEdit_inputIndexForce->setEnabled(false);
            ui->lineEdit_inputThumbBendForce->setEnabled(false);
            ui->lineEdit_inputThumbRotationForce->setEnabled(false);

            ui->lineEdit_inputLittleSpeed->setEnabled(false);
            ui->lineEdit_inputRingSpeed->setEnabled(false);
            ui->lineEdit_inputMiddleSpeed->setEnabled(false);
            ui->lineEdit_inputIndexSpeed->setEnabled(false);
            ui->lineEdit_inputThumbBendSpeed->setEnabled(false);
            ui->lineEdit_inputThumbRotationSpeed->setEnabled(false);

            ui->lineEdit_showLittle->clear();
            ui->lineEdit_showRing->clear();
            ui->lineEdit_showMiddle->clear();
            ui->lineEdit_showIndex->clear();
            ui->lineEdit_showThumbBend->clear();
            ui->lineEdit_showThumbRotation->clear();
        }
    });
}

void InspireRobotsWidget::on_pushButton_run_clicked()
{
    if (!m_is_init)
    {
        return;
    }

    QJsonObject start_obj;
    start_obj["slave_id"] = m_device_id;
    start_obj["angle_set0"] = ui->lineEdit_inputLittleAngle->text().toInt();
    start_obj["angle_set1"] = ui->lineEdit_inputRingAngle->text().toInt();
    start_obj["angle_set2"] = ui->lineEdit_inputMiddleAngle->text().toInt();
    start_obj["angle_set3"] = ui->lineEdit_inputIndexAngle->text().toInt();
    start_obj["angle_set4"] = ui->lineEdit_inputThumbBendAngle->text().toInt();
    start_obj["angle_set5"] = ui->lineEdit_inputThumbRotationAngle->text().toInt();


    QJsonObject start_root;
    start_root["start"] = start_obj;

    QJsonObject root;
    root["InspireRobotsPlugin"] = start_root;

    sendRequest(root, [=](QJsonArray){});
}

void InspireRobotsWidget::on_pushButton_setForce_clicked()
{
    if (!m_is_init)
    {
        return;
    }

    QJsonObject set_obj;
    set_obj["slave_id"] = m_device_id;
    set_obj["force_set0"] = ui->lineEdit_inputLittleForce->text().toInt();
    set_obj["force_set1"] = ui->lineEdit_inputRingForce->text().toInt();
    set_obj["force_set2"] = ui->lineEdit_inputMiddleForce->text().toInt();
    set_obj["force_set3"] = ui->lineEdit_inputIndexForce->text().toInt();
    set_obj["force_set4"] = ui->lineEdit_inputThumbBendForce->text().toInt();
    set_obj["force_set5"] = ui->lineEdit_inputThumbRotationForce->text().toInt();


    QJsonObject set_root;
    set_root["set_force"] = set_obj;

    QJsonObject root;
    root["InspireRobotsPlugin"] = set_root;

    sendRequest(root, [=](QJsonArray){});
}

void InspireRobotsWidget::on_pushButton_setSpeed_clicked()
{
    if (!m_is_init)
    {
        return;
    }

    QJsonObject set_obj;
    set_obj["slave_id"] = m_device_id;
    set_obj["speed_set0"] = ui->lineEdit_inputLittleSpeed->text().toInt();
    set_obj["speed_set1"] = ui->lineEdit_inputRingSpeed->text().toInt();
    set_obj["speed_set2"] = ui->lineEdit_inputMiddleSpeed->text().toInt();
    set_obj["speed_set3"] = ui->lineEdit_inputIndexSpeed->text().toInt();
    set_obj["speed_set4"] = ui->lineEdit_inputThumbBendSpeed->text().toInt();
    set_obj["speed_set5"] = ui->lineEdit_inputThumbRotationSpeed->text().toInt();


    QJsonObject set_root;
    set_root["set_speed"] = set_obj;

    QJsonObject root;
    root["InspireRobotsPlugin"] = set_root;

    sendRequest(root, [=](QJsonArray){});
}


void InspireRobotsWidget::showEvent(QShowEvent*)
{
    m_poller->openTimer();
}

void InspireRobotsWidget::hideEvent(QHideEvent*)
{
    m_poller->closeTimer();
}

